<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://www.zjzit.cn>
// +----------------------------------------------------------------------

namespace Home\Controller;

use Think\Controller;
use Com\Wechat;
use Com\Slog;

class WechatController extends Controller{
    /**
     * 微信消息接口入口
     * 所有发送到微信的消息都会推送到该操作
     * 所以，微信公众平台后台填写的api地址则为该操作的访问地址
     */
    public function index($id = ''){
        //hello
       //初始化 SocketLog
        Slog::config(array(
            'enable'=>true,//是否打印日志的开关
            'host'=>'slog.thinkphp.cn',//websocket服务器地址，默认localhost
            'optimize'=>false,//是否显示利于优化的参数，如果运行时间，消耗内存等，默认为false
            'show_included_files'=>false,//是否显示本次程序运行加载了哪些文件，默认为false
            'error_handler'=>false,//是否接管程序错误，将程序错误显示在console中，默认为false
            'force_client_id'=>'slog_9bc5eb',//日志强制记录到配置的client_id,默认为空
            'allow_client_ids'=>array()////限制允许读取日志的client_id，默认为空,表示所有人都可以获得日志。
        ));
        Slog::big('Wechat index() begin');

        $token = '12345'; //微信后台填写的TOKEN

        /* 加载微信SDK */
        $wechat = new Wechat($token);

        /* 获取请求信息 */
        $data = $wechat->request();


        if($data && is_array($data)){

            /**
             * 你可以在这里分析数据，决定要返回给用户什么样的信息
             * 接受到的信息类型有9种，分别使用下面九个常量标识
             * Wechat::MSG_TYPE_TEXT       //文本消息
             * Wechat::MSG_TYPE_IMAGE      //图片消息
             * Wechat::MSG_TYPE_VOICE      //音频消息
             * Wechat::MSG_TYPE_VIDEO      //视频消息
             * Wechat::MSG_TYPE_MUSIC      //音乐消息
             * Wechat::MSG_TYPE_NEWS       //图文消息（推送过来的应该不存在这种类型，但是可以给用户回复该类型消息）
             * Wechat::MSG_TYPE_LOCATION   //位置消息
             * Wechat::MSG_TYPE_LINK       //连接消息
             * Wechat::MSG_TYPE_EVENT      //事件消息
             *
             * 事件消息又分为下面五种
             * Wechat::MSG_EVENT_SUBSCRIBE          //订阅
             * Wechat::MSG_EVENT_SCAN               //二维码扫描
             * Wechat::MSG_EVENT_LOCATION           //报告位置
             * Wechat::MSG_EVENT_CLICK              //菜单点击
             * Wechat::MSG_EVENT_MASSSENDJOBFINISH  //群发消息成功
             */

            $content = ''; //回复内容，回复不同类型消息，内容的格式有所不同
            $type    = ''; //回复消息的类型
            //Slog::big($data);  //一般日志

            /* 响应当前请求(自动回复) */
            //$wechat->response($content, $type);
            //
            $event = $data['Event'];
            $content = $data['Content'];
            $MsgType = $data['MsgType'];
            $ToUserName = $data['ToUserName'];

            //取得传入的消息类型 ，如果是event，则判断$event 如果是SCAN 进入扫码回复
            //如果是CLICK 则进入点击回复 ,根据appid 和 EventKey 去数据库查询回复的内容
            if (($MsgType=='event')&&($event=='SCAN')){
                $ticket = $data['Ticket'];
                //成功收到用户扫码
                $openid = $data['FromUserName'];
                $ToUserName = $data['ToUserName'];
                $patients = D('wx_patient')->where("(weixinhao='$ToUserName')and (openid='$openid') and (flag='1')")->select();
                if (count($patients)>0){
                    $wechat->replyText("您已经关联至本院微信账户，请不要重复扫描二维码");
                    return;
                }
                $patients = D('wx_patient')->where("ticket='".$ticket."'")->select();
               // $wechat->replyText("ticket=".$ticket);
                if (count($patients)>0){
                    $patient = $patients[0];
                    //$wechat->replyText("pati_name=".$patient['pati_name'].$patient['flag']);
                    if ($patient['flag']=='1'){
                        $wechat->replyText($patient['pati_name']."已经关联至本院微信账户，请不要重复扫描二维码");
                        return;
                    } else {
                        $pati_name = $patient['pati_name'];
                        $patient['openid']=$openid;
                        $patient['flag']='1';
                        $patient['linktime']=time();
                        D('wx_patient')->save($patient);
                        //需要发送模版消息
                        $this-> checkuser($wechat,$ToUserName,$openid);
                        return;
                    }
                } else {
                    $wechat->replyText("二维码验证错误，请重新扫描");
                    return;
                }
            } elseif (($MsgType=="event")&&(($event=="CLICK")||($event=="subscribe")||($event=="unsubscribe"))){
                $CreateTime = $data['CreateTime'];

                $FromUsername = $data['FromUserName'];
                $ToUserName = $data["ToUserName"];
                if ($event=="subscribe") {
                    $EventKey = "subscribe";
                } else if ($event=="unsubscribe") {
                    $EventKey = "unsubscribe";

                    //取消订阅用户删除绑定标志
                    //$openid = $data['FromUserName'];
                    $patients = D('wx_patient')->where("(weixinhao='$ToUserName')and (openid='$FromUsername') and (flag='1')")->select();
                    if (count($patients)>0){
                        $patient = $patients[0];
                        $patient['openid']='';
                        $patient['flag']='0';
                        $patient['linktime']=0;
                        D('wx_patient')->save($patient);
                    }

                } else {
                    $EventKey = $data["EventKey"];
                }
	           // Slog::big($ToUserName);
               // Slog::big("appid='$ToUserName' and eventkey='$EventKey'");


                $events= D('wx_event_data')->where("weixinhao='$ToUserName' and eventkey='$EventKey'")->select();
                //Slog::big($events);

                if (count($events)>0){
                    $eventdata = $events[0];

                    if ($eventdata["datatype"]=="news"){
                        $messageid=$eventdata['id'];
                        $newss = D('wx_all_news')->where("eventid=$messageid")->select();

                        if (count($newss)>0){
                            $news=$newss[0]; //回复单图文
                            if (count($newss)>1){//如果 nextid >0 回复多图文
                                $newsarray=array();
                                for ($i=0;$i<count($newss);$i=$i+1){
                                    $news= Array($newss[$i]["title"],$newss[$i]["description"],$newss[$i]["url"],$newss[$i]["picurl"]);
                                    $newsarray[]=$news;
                                }
                                $wechat->replyNewsAllInOne($newsarray);
                                return;
                            } else { //回复单图文
                                $wechat->replyNewsOnce($news["title"],$news["description"],$news["url"],$news["picurl"]);
                                return;
                            }
                        } else{
                            $wechat->replyText("实在对不住，$EventKey 没有回复图文");
                            return;
                        }
                    } elseif ($eventdata["datatype"]=="text"){//回复纯文本
                        $messageid=$eventdata['id'];
                        // slog("messageid=$messageid");
                        $this->replyEventText($wechat,$messageid);
                    } else { //对于存在event事件又不是 news和text，目前设定执行函数

                        $funname = $eventdata["datatype"];
                        Slog::big($funname);
                        call_user_func(array($this, $funname),$wechat,$ToUserName, $FromUsername);
                        Slog::big($funname);
                        return ;
                    }

                } else {
                    $wechat->replyText("对不起，微信服务出现异常，$EventKey 没有找到");
                    return ;
                }

            }  elseif ($MsgType=='text'){//如果用户回复文本
                $events= D('wx_event_data')->where("weixinhao='$ToUserName' and eventkey='$content'")->select();
                if (count($events)>0){
                    $eventdata = $events[0];
                    if ($eventdata["datatype"]=="news"){
                        $messageid=$eventdata['id'];
                        $newss = D('wx_all_news')->where("eventid=$messageid")->select();

                        if (count($newss)>0){
                            if (count($newss)>1){//如果 nextid >0 回复多图文
                                $newsarray=array();
                                for ($i=0;$i<count($newss);$i=$i+1){
                                    $news= Array($newss[$i]["title"],$newss[$i]["description"],$newss[$i]["url"],$newss[$i]["picurl"]);
                                    $newsarray[]=$news;
                                }
                                $wechat->replyNewsAllInOne($newsarray);
                                return;
                            } else { //回复单图文
                                $news=$newss[0]; //回复单图文
                                $wechat->replyNewsOnce($news["title"],$news["description"],$news["url"],$news["picurl"]);
                                return;
                            }

                        } else{
                            $wechat->replyText("实在对不住，$EventKey 没有回复图文");
                            return;
                        }
                    } elseif ($eventdata["datatype"]=="text"){//回复纯文本
                        $messageid=$eventdata['id'];
                        //slog("messageid=$messageid");
                        $this->replyEventText($wechat,$messageid);
                    } else { //对于存在event事件又不是 news和text，目前设定执行函数

                        $funname = $eventdata["datatype"];
                        call_user_func(array($this, $funname),$wechat,$ToUserName, $FromUsername);
                        return ;
                    }

                } else {
                    return 'success';
                }


            }elseif (($MsgType=="event")&&($event=="unsubscribe")){

                $wechat->replyText("实在对不住，目前我只会回复这个哈");
                return ;
            }
            //$wechat->replyText("您好！您的信息已经发送给相关工作人员，请稍候即可得到回复通知");
            return 'success';

            /**
             * 响应当前请求还有以下方法可以只使用
             * 具体参数格式说明请参考文档
             *
             * $wechat->replyText($text); //回复文本消息
             * $wechat->replyImage($media_id); //回复图片消息
             * $wechat->replyVoice($media_id); //回复音频消息
             * $wechat->replyVideo($media_id, $title, $discription); //回复视频消息
             * $wechat->replyMusic($title, $discription, $musicurl, $hqmusicurl, $thumb_media_id); //回复音乐消息
             * $wechat->replyNews($news, $news1, $news2, $news3); //回复多条图文消息
             * $wechat->replyNewsOnce($title, $discription, $url, $picurl); //回复单条图文消息
             *
             */
        }
    }
    //回复多图文功能
    function buildNewsArray($msgid,$newsarray){
        $n = D('wx_all_news')->field('title,url,description,picurl')->where("eventid=$msgid")->select();
        return $n;
        if (count($n)>0){

            $news=$n[0];
            if ($news["nextid"]>0){//回复多图文
                $nn = Array($news["title"],$news["description"],$news["url"],$news["picurl"]);
                $newsarray[]=$nn;
                return $this->buildNewsArray($news['nextid'],$newsarray);
            } else {
                $nn = Array($news["title"],$news["description"],$news["url"],$news["picurl"]);
                $newsarray[]=$nn;
                return $newsarray;
            }
        } else {
            return $newsarray;
        }

    }
    function replyEventText($wechat_instance,$msgid){
        $texts = D('wx_all_text')->where("eventid=$msgid")->select();
        if (count($texts)>0){
            $text=$texts[0]; //回复文本
            $wechat_instance->replyText($text['text']);
            return;
        }else {
            $wechat_instance->replyText("实在对不住，没有回复文本");
            return;//请稍后重试，
        }
    }
    /*

	    我的卡号程序进入点
        传入参数 1)wechat实例
                2)微信号的appid
                3)用户的openid
        程序功能 查询用户账号，并将信息以templete_key=“key_bind”的模版发出
               如果未找到已绑定的用户 则回复文本消息1
               未找到模版 则回复文本消息2
    */
    function checkuser($wechat_instance,$wxid,$openid){//检测用户

        $patients = D('wx_patient')->where("weixinhao='$wxid' and openid='$openid'")->select();
        $templetes =D('wx_all_templete')->where("weixinhao='$wxid' and templete_key='key_bind'")->select();
        if (count($templetes)==0){
            $this->replyEventText($wechat_instance,2);   //回复指定消息
            return;
        }
        $templete_id=$templetes[0]["templete_id"];
        $first=$templetes[0]["first"];
        $remark=$templetes[0]["remark"];

        if (count($patients)>0){
            $data = Array('touser'=>$openid,
                'template_id'=>$templete_id,
                'topcolor'=>'#FF0000',
                'url'=>'',
                'data'=>Array(
                    'first'   =>Array("color"=>"#173177","value"=>$first),
                    'keyword1'=>Array("color"=>"#173177","value"=>$patients[0]["sick_no"]),
                    'keyword2'=>Array("color"=>"#173177","value"=>$patients[0]["pati_name"]),
                    'remark'  =>Array("color"=>"#173177","value"=>$remark)
                ));

            $access = $this->getAccess($wxid);
            $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access;
            $jsondata = json_encode($data);

            $json=self::http_request_json_post($url,$jsondata);
            $returndata = json_decode($json,true);
            return;
        } else {
            $this->replyEventText($wechat_instance,1);   //回复指定消息
            return;
        }
    }


    //因为url是https 所有请求不能用file_get_contents,用curl请求json 数据
    function http_request_json($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    function http_request_json_post($url,$data){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt ( $ch, CURLOPT_POST, 1 );
        curl_setopt ( $ch, CURLOPT_HEADER, 0 );
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    //取得当前myappid的access_token
    public function getAccess($wxid){
        $appdatas = D('wx_appinfo')->where("weixinhao='$wxid'")->select();
        $appdata = $appdatas[0];
        $appid= $appdata['wxappid'];
        $secret= $appdata['secret'];
        $access_token= $appdata['access_token'];
        $expire = $appdata['expire'];
        if ($expire>time()){
            return $access_token;
        }

        //slog('appid='.$appid);
        //slog('secret='.$secret);

        $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
        $json=self::http_request_json($url);//这个地方不能用file_get_contents
        $data=json_decode($json,true);
        if($data['access_token']){
            $appdata['expire']= time()+$data['expires_in'];
            $appdata['access_token']= $data['access_token'];
            D('wx_appinfo')->save($appdata);
            return $data['access_token'];
        }else{
            return "获取access_token错误";
        }
    }
    //取得当前myappid的EventData
    public function getEventData($wxid)
    {
        header("Content-type: application/json; charset=utf-8");
        $datas = D('wx_event_data')->where("weixinhao='$wxid'")->select();
        $data=Array();
        $data['result']="0";
        $data['data']=$datas;
        die(json_encode($data));

    }
    public function setEventNews($wxid,$event){


        $postdata = urldecode(file_get_contents("php://input"));
        $requestdata = json_decode($postdata, TRUE);
/*
        $result=Array();
        $result['wxid']=$wxid;
        $result['event']=$event;
        $result['data']=$requestdata;
        die(json_encode($result));
*/
        $events= D('wx_event_data')->where("weixinhao='$wxid' and eventkey='$event'")->select();
        if (count($events)>0) {
            //存在原记录
            $eventid=$events[0]["id"];
            D('wx_all_news')->where("eventid=$eventid")->delete();
            
        } else {
            $events = Array();
            $events["weixinhao"] = $wxid;
            $events["eventkey"] = $event;
            $events["datatype"] = "news";
            //->create();
            $eventid=D("wx_event_data")->add($events);
            $events["id"] = $eventid;
            D("wx_event_data")->save($events);

        }
        //将post过来的记录保存
        $data = $requestdata;//["data"];
        for ($i=0; $i<count($data); $i=$i+1) {
            D("wx_all_news")->create();
            $data1 = array();
            $data1["eventid"]=$eventid;
            $data1["url"]=$data[$i]["url"];
            $data1["title"]=$data[$i]["title"];
            $data1["description"]=$data[$i]["description"];
            $data1["picurl"]=$data[$i]["picurl"];
/*
            $result=Array();
            $result['wxid']=$wxid;
            $result['event']=$event;
            $result['data']=$data1;
            die(json_encode($result));
*/
            D("wx_all_news")->add($data1);
        }
        $result=Array();
        $result['result']="0";
        die(json_encode($result));


    }
}
?>
